package com.hamilton.erik.pt.mobile.android;

import java.text.ParseException;
import java.util.Calendar;
import java.util.HashMap;
import java.util.Map;

import org.json.JSONObject;

import android.app.Dialog;
import android.app.ProgressDialog;
import android.content.Intent;
import android.os.Bundle;
import android.text.TextUtils;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.ArrayAdapter;
import android.widget.DatePicker;
import android.widget.EditText;
import android.widget.Spinner;
import android.widget.TimePicker;

import com.android.volley.Response;
import com.hamilton.erik.pt.core.enumeration.Gender;
import com.hamilton.erik.pt.core.model.Animal;
import com.hamilton.erik.pt.core.util.DateTimeUtil;
import com.hamilton.erik.pt.core.util.StringUtil;
import com.hamilton.erik.pt.mobile.android.app.DateTimePickerDialog;
import com.hamilton.erik.pt.mobile.android.volley.response.error.listener.DisplayErrorErrorListener;
import com.hamilton.erik.pt.mobile.client.VolleyJsonRestClient;
import com.hamilton.erik.pt.mobile.util.ResultUtil;
import com.hamilton.erik.pt.mobile.util.ServerUtil;

public class EditAnimalActivity extends EditDataActivity {

	// ID for DatePicker Dialog
	private final int BIRTHDAY_DATE_PICKER_DIALOG_ID = 0;
	private final int PURCHASE_DATE_PICKER_DIALOG_ID = 1;
	
	private Animal animal;
	private ProgressDialog progressDialog = null;
	
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_edit_animal);

		findViewById(R.id.animal_edit_birth_date_field).setOnClickListener(
				new OnClickListener() {
					@SuppressWarnings("deprecation")
					@Override
					public void onClick(View view) {
					    showDialog(BIRTHDAY_DATE_PICKER_DIALOG_ID);
					}
				});
		
		findViewById(R.id.animal_edit_purchase_date_field).setOnClickListener(
				new OnClickListener() {
					@SuppressWarnings("deprecation")
					@Override
					public void onClick(View view) {
					    showDialog(PURCHASE_DATE_PICKER_DIALOG_ID);
					}
				});
		
		findViewById(R.id.animal_edit_save_edit_button).setOnClickListener(
				new View.OnClickListener() {
					@Override
					public void onClick(View view) {
						save();
					}
				});
		
		findViewById(R.id.animal_edit_cancel_edit_button).setOnClickListener(
				new View.OnClickListener() {
					@Override
					public void onClick(View view) {
						cancel();
					}
				});
		
		animal = (Animal) getIntent().getSerializableExtra(
				getString(R.string.extra_animal_object));

		if (!TextUtils.isEmpty(animal.getName())) {
			setTitle("Editing " + animal.getName());
		}

		populateFields();
	}

	protected void populateFields() {
		if (animal != null) {
			String temp;
			
			temp = animal.getName();
			if (!TextUtils.isEmpty(temp)) {
				EditText nameEditText = (EditText) findViewById(R.id.animal_edit_name_field);
				nameEditText.setText(temp);
			}

			temp = animal.getGenus();
			if (!TextUtils.isEmpty(temp)) {
				EditText genusEditText = (EditText) findViewById(R.id.animal_edit_genus_field);
				genusEditText.setText(temp);
			}

			temp = animal.getSpecies();
			if (!TextUtils.isEmpty(temp)) {
				EditText speciesEditText = (EditText) findViewById(R.id.animal_edit_species_field);
				speciesEditText.setText(temp);
			}

			temp = animal.getType();
			if (!TextUtils.isEmpty(temp)) {
				EditText typeEditText = (EditText) findViewById(R.id.animal_edit_type_field);
				typeEditText.setText(temp);
			}

			Spinner genderDropDown = (Spinner) findViewById(R.id.animal_edit_gender_drop_down);
			ArrayAdapter<Gender> genderDropDownAdapter =
					new ArrayAdapter<Gender>(this, android.R.layout.simple_spinner_item, Gender.values());
			genderDropDown.setAdapter(genderDropDownAdapter);
			if (animal.getGender() != null) {
				int dropDownPosition = genderDropDownAdapter.getPosition(animal.getGender());
				genderDropDown.setSelection(dropDownPosition);
			}

			temp = animal.getBirthDate();
			if (!TextUtils.isEmpty(temp)) {
				EditText birthDateEditText = (EditText) findViewById(R.id.animal_edit_birth_date_field);
				birthDateEditText.setText(temp);
			}

			temp = animal.getPurchaseDate();
			if (!TextUtils.isEmpty(temp)) {
				EditText purchaseDateEditText = (EditText) findViewById(R.id.animal_edit_purchase_date_field);
				purchaseDateEditText.setText(temp);
			}
		}
	}
	
	protected boolean validateFields() {
		boolean valid = true;
		View focusView = null;
		
		EditText typeField = ((EditText) findViewById(R.id.animal_edit_type_field));
		if (TextUtils.isEmpty(typeField.getText().toString())) {
			typeField.setError(getString(R.string.error_field_required));
			focusView = typeField;
			valid = false;
		}
		
		EditText nameField = ((EditText) findViewById(R.id.animal_edit_name_field));
		if (TextUtils.isEmpty(nameField.getText().toString())) {
			nameField.setError(getString(R.string.error_field_required));
			focusView = nameField;
			valid = false;
		}
		
		// Gender is also a required field, but it is a drop down and will always
		// have a valid value.
		
		if (!valid) {
			focusView.requestFocus();
		}
		
		return valid;
	}
	
	protected void save() {
		
		if(validateFields()) {
			StringBuilder url = new StringBuilder(ServerUtil.getInstance().buildAnimalPath());
			url.append("/upsert");
			
			Map<String, String> params = new HashMap<String, String>();
			String temp;
			
			if(animal.getId() != null) {
				params.put("id", animal.getId().toString().trim());
			}
			
			if(animal.getUserName() != null) {
				params.put("userName", animal.getUserName().trim());
			}
			
			temp = ((EditText)findViewById(R.id.animal_edit_type_field)).getText().toString().trim();
			if(!TextUtils.isEmpty(temp)) {
				params.put("type", temp);
				animal.setType(temp);
			}
			
			temp = ((EditText)findViewById(R.id.animal_edit_genus_field)).getText().toString().trim();
			if(!TextUtils.isEmpty(temp)) {
				params.put("genus", StringUtil.capitalizeFirstLetter(temp));
				animal.setGenus(StringUtil.capitalizeFirstLetter(temp));
			}
			
			temp = ((EditText)findViewById(R.id.animal_edit_species_field)).getText().toString().trim();
			if(!TextUtils.isEmpty(temp)) {
				params.put("species", temp.toLowerCase());
				animal.setSpecies(temp.toLowerCase());
			}
			
			temp = ((EditText)findViewById(R.id.animal_edit_name_field)).getText().toString().trim();
			if(!TextUtils.isEmpty(temp)) {
				params.put("name", temp);
				animal.setName(temp);
			}
			
			temp = ((EditText)findViewById(R.id.animal_edit_birth_date_field)).getText().toString().trim();
			if(!TextUtils.isEmpty(temp)) {
				params.put("birthDate", temp);
				animal.setBirthDate(temp);
			}
			
			temp = ((EditText)findViewById(R.id.animal_edit_purchase_date_field)).getText().toString().trim();
			if(!TextUtils.isEmpty(temp)) {
				params.put("purchaseDate", temp);
				animal.setPurchaseDate(temp);
			}
			
			temp = ((Spinner)findViewById(R.id.animal_edit_gender_drop_down)).getSelectedItem().toString().trim();
			if(!TextUtils.isEmpty(temp)) {
				params.put("gender", temp);
				animal.setGender(Gender.fromValue(temp));
			}
			
			if (progressDialog == null) {
		        progressDialog = new ProgressDialog(this);
		        progressDialog.setTitle(getString(R.string.progress_uploading_title));
		        progressDialog.setMessage(getString(R.string.edit_animal_progress_saving_animal));
		    }
		    progressDialog.show();
		    
			VolleyJsonRestClient.getClient()
					.putJsonObject(
							url.toString(),
							new SaveSuccessListener(), 
							new DisplayErrorErrorListener(this, progressDialog),
							params);
		}
	}
	
	protected void cancel() {
		finish();
	}

	@Override
	public boolean onCreateOptionsMenu(Menu menu) {

		// Inflate the menu; this adds items to the action bar if it is present.
		getMenuInflater().inflate(R.menu.edit_animal, menu);
		return true;
	}

	@Override
	public boolean onOptionsItemSelected(MenuItem item) {
		// Handle action bar item clicks here. The action bar will
		// automatically handle clicks on the Home/Up button, so long
		// as you specify a parent activity in AndroidManifest.xml.
		switch(item.getItemId()) {
			case R.id.action_edit_animal_save :
				save();
				return true;
			default :
				return super.onOptionsItemSelected(item);
		}
	}

	@Override
	protected Dialog onCreateDialog(int id) {
		switch(id) {
		
			case BIRTHDAY_DATE_PICKER_DIALOG_ID :
				EditText birthDateEditText = (EditText) findViewById(R.id.animal_edit_birth_date_field);
				Calendar birthDateCalendar = Calendar.getInstance();
				if(!TextUtils.isEmpty(
						birthDateEditText.getText().toString())) {
					try {
						birthDateCalendar.setTime(
								DateTimeUtil.standardDateTimeStringToDate(
										birthDateEditText.getText().toString()));
					} catch (ParseException ignore) {
						// Nothing we can do here, use the default calendar instance
						Log.d("EditAnimalActivity", "Unable to pare standard date to string - " + ignore.getMessage());
					}
				}
				
				DateTimePickerDialog birthDateDtpd = new DateTimePickerDialog(this, 
						birthDateDateTimeSetListener,
						birthDateCalendar.get(Calendar.YEAR),
						birthDateCalendar.get(Calendar.MONTH),
						birthDateCalendar.get(Calendar.DAY_OF_MONTH),
						birthDateCalendar.get(Calendar.HOUR_OF_DAY),
						birthDateCalendar.get(Calendar.MINUTE));
				
				return birthDateDtpd;
				
			case PURCHASE_DATE_PICKER_DIALOG_ID :
				EditText purchaseDateEditText = (EditText) findViewById(R.id.animal_edit_purchase_date_field);
				Calendar purchaseDateCalendar = Calendar.getInstance();
				if(!TextUtils.isEmpty(
						purchaseDateEditText.getText().toString())) {
					try {
						purchaseDateCalendar.setTime(
								DateTimeUtil.standardDateTimeStringToDate(
										purchaseDateEditText.getText().toString()));
					} catch (ParseException ignore) {
						// Nothing we can do here, use the default calendar instance
						Log.d("EditAnimalActivity", "Unable to pare standard date to string - " + ignore.getMessage());
					}
				}
				
				DateTimePickerDialog purchaseDateDtpd = new DateTimePickerDialog(this, 
						purchaseDateDateTimeSetListener,
						purchaseDateCalendar.get(Calendar.YEAR),
						purchaseDateCalendar.get(Calendar.MONTH),
						purchaseDateCalendar.get(Calendar.DAY_OF_MONTH),
						purchaseDateCalendar.get(Calendar.HOUR_OF_DAY),
						purchaseDateCalendar.get(Calendar.MINUTE));
				
				return purchaseDateDtpd;
		}
		
		return null;
	}
	
	private DateTimePickerDialog.OnDateTimeSetListener birthDateDateTimeSetListener =
			new DateTimePickerDialog.OnDateTimeSetListener() {
				
				@Override
				public void onDateTimeSet(DatePicker datePicker, TimePicker timePicker,
						int year, int monthOfYear, int dayOfMonth, int hourOfDay, int minute) {
					Calendar calendar = Calendar.getInstance();
					calendar.set(Calendar.YEAR, year);
					calendar.set(Calendar.MONTH, monthOfYear);
					calendar.set(Calendar.DAY_OF_MONTH, dayOfMonth);
					calendar.set(Calendar.HOUR_OF_DAY, hourOfDay);
					calendar.set(Calendar.MINUTE, minute);
					
					EditText birthDateEditText = (EditText) findViewById(R.id.animal_edit_birth_date_field);
					birthDateEditText.setText(
							DateTimeUtil
								.dateToStandardDateTimeString(
											calendar.getTime()));
				}
			};
			
	private DateTimePickerDialog.OnDateTimeSetListener purchaseDateDateTimeSetListener =
			new DateTimePickerDialog.OnDateTimeSetListener() {
				
				@Override
				public void onDateTimeSet(DatePicker datePicker, TimePicker timePicker,
						int year, int monthOfYear, int dayOfMonth, int hourOfDay, int minute) {
					Calendar calendar = Calendar.getInstance();
					calendar.set(Calendar.YEAR, year);
					calendar.set(Calendar.MONTH, monthOfYear);
					calendar.set(Calendar.DAY_OF_MONTH, dayOfMonth);
					calendar.set(Calendar.HOUR_OF_DAY, hourOfDay);
					calendar.set(Calendar.MINUTE, minute);
					
					EditText purchaseDateEditText = (EditText) findViewById(R.id.animal_edit_purchase_date_field);
					purchaseDateEditText.setText(
							DateTimeUtil
								.dateToStandardDateTimeString(
											calendar.getTime()));
				}
			};
			
	private class SaveSuccessListener implements Response.Listener<JSONObject> {

		@Override
		public void onResponse(JSONObject response) {
			if (progressDialog != null && progressDialog.isShowing()) {
				progressDialog.dismiss();
			}
			
			Intent result = new Intent();
			result.putExtra(getString(R.string.extra_animal_object), animal);
			
			setResult(ResultUtil.RESULT_SUCCESS, result);
			finish();
		}
		
	}

}
